<template>
  <a-popover
    v-model:popup-visible="visible"
    trigger="click"
    position="rb"
    @popup-visible-change="onSearch('')"
  >
    <template #content>
      <div class="icon-container">
        <a-input-search
          placeholder="搜索图标名称"
          press-enter
          style="width: 100%"
          allow-clear
          search-button
          @search="onSearch"
          @change="onSearch"
        />
        <div class="mt-4"></div>
        <div class="icon-wrapper">
          <a-row :wrap="true">
            <a-col v-for="item of iconNames" :key="item" :span="4">
              <div
                class="flex justify-center items-center flex-col icon-item"
                @click="onSelectItem(item)"
              >
                <component
                  :is="
                    item.startsWith('Icon')
                      ? item
                      : 'icon' + item.replace(/([A-Z])/g, '-$1').toLowerCase()
                  "
                  style="font-size: 26px"
                />
                <a-tooltip :content="item">
                  <div class="label-name">{{ item }}</div>
                </a-tooltip>
              </div>
            </a-col>
          </a-row>
        </div>
        <div class="mt-1"></div>
        <a-pagination
          size="mini"
          :page-size="pageSize"
          :total="total"
          :show-size-changer="false"
          @change="onPageChange"
        />
      </div>
    </template>
    <a-button v-if="!selectedItem" type="primary">请选择图标</a-button>
    <a-button v-else status="success">
      已选择
      <component :is="selectedItem" class="ml-2" />
    </a-button>
    <a-button
      v-if="selectedItem"
      class="ml-2"
      shape="circle"
      status="warning"
      @click="clear"
      ><icon-delete
    /></a-button>
  </a-popover>
</template>

<script lang="ts" setup>
  import * as Icons from '@arco-design/web-vue/es/icon';
  import * as IconPacks from '@icon-park/vue-next';
  import { useClipboard } from '@vueuse/core';
  import { kebabCase } from 'lodash-es';
  import { ref, watch } from 'vue';

  const emit = defineEmits(['onSelect', 'update:modelValue', 'clear']);
  const props = defineProps({
    modelValue: {
      type: String,
      default: '',
    },
    enableCopy: {
      type: Boolean,
      default: false,
    },
  });
  const iconList = Object.keys(Icons)
    .filter((it) => it !== 'default')
    .concat(Object.keys(IconPacks).filter((it) => it !== 'default'));
  const pageSize = 36;
  const currentPage = ref(1);
  const iconNames = ref(iconList.slice(0, pageSize));
  const searchList = ref<Array<string>>([]);
  const total = ref(iconList.length);
  const visible = ref(false);
  const selectedItem = ref(props.modelValue);
  watch(
    () => props.modelValue,
    (newVal) => {
      selectedItem.value = newVal;
    }
  );
  function onPageChange(page: number) {
    currentPage.value = page;
    iconNames.value =
      searchList.value.length === 0
        ? iconList.slice((page - 1) * pageSize, page * pageSize)
        : searchList.value.slice((page - 1) * pageSize, page * pageSize);
  }
  function onSearch(searchValue: string) {
    if (searchValue) {
      const temp = searchValue.toLowerCase();
      searchList.value = iconList.filter((it) => {
        return it.toLowerCase().indexOf(temp) > -1;
      });
      total.value = searchList.value.length;
      iconNames.value = searchList.value.slice(0, pageSize);
    } else {
      searchList.value = [];
      total.value = iconList.length;
      iconNames.value = iconList.slice(
        (currentPage.value - 1) * pageSize,
        currentPage.value * pageSize
      );
    }
  }
  async function onSelectItem(item: string) {
    if (!item.startsWith('Icon')) {
      item = `Icon${item}`;
    }
    item = kebabCase(item);
    selectedItem.value = item;
    visible.value = false;
    MessageInfo.success(`已选择并且复制成功 ${item} 图标`);
    if (props.enableCopy) {
      const { isSupported, copied, copy } = useClipboard();
      if (isSupported) {
        await copy(`<${item} />`);
        if (copied) {
          MessageInfo.success(`已选择并且复制成功 ${item} 图标`);
        }
      }
    }
    emit('onSelect', item);
    emit('update:modelValue', item);
  }

  const clear = () => {
    selectedItem.value = '';
    emit('update:modelValue', '');
    emit('clear');
  };
</script>

<style lang="less" scoped>
  :deep(.arco-pagination) {
    justify-content: center;
  }

  .icon-container {
    width: 360px;
    overflow: hidden;
    text-align: center;

    .icon-wrapper {
      min-height: 300px;

      .icon-item {
        height: 80px;
        overflow: hidden;
        text-align: center;

        .label-name {
          width: 70%;
          margin: 0 auto;
          margin-top: 5px;
          overflow: hidden;
          color: #888;
          font-size: 12px;
          text-overflow: ellipsis;
          word-wrap: normal;
        }

        .arco-icon {
          transform: scale(1);
          transition: transform 0.2s linear;
        }

        &:hover {
          cursor: pointer;

          .arco-icon {
            transform: scale(1.5);
            transition: transform 0.2s linear;
          }
        }
      }
    }
  }
</style>
